package com.briup.es.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.briup.es.config.exception.ServiceException;
import com.briup.es.config.response.ResultCode;
import com.briup.es.domain.bean.User;
import com.briup.es.domain.dto.UserDTO;
import com.briup.es.domain.dto.UserLoginDTO;
import com.briup.es.service.UserService;
import com.briup.es.mapper.UserMapper;
import com.briup.es.util.BeanUtil;
import com.briup.es.util.JwtUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Override
    public Map<String, Object> login(UserLoginDTO loginDTO) {
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();

        User user = queryByUsername(username);

        if (user == null) {
            throw new ServiceException(ResultCode.USER_IS_NOT_EXISTS);
        }
        // 用户存在，继续比较用户的密码
        if (!password.equals(user.getPassword())) {
            throw new ServiceException(ResultCode.PASSWORD_IS_ERROR);
        }
        // 密码也相同，进一步校验账号是否被封禁
        if (user.getStatus() == 1) {
            throw new ServiceException(ResultCode.ACCOUNT_IS_UNABLE);
        }

        // 根据用户信息生成 token （token需要具备 防篡改、携带部分数据、过期失效 等功能）
        Map<String, Object> claims = Map.of("userId", user.getId(),
                "username", user.getUsername());
        // 签发token
        String token = JwtUtil.sign(claims);

        return Map.of("jwt", token, "userInfo", user);
    }

    @Override
    public void register(UserDTO userDTO) {
        User userFromDB = queryByUsername(userDTO.getUsername());
        if (userFromDB != null) {
            throw new ServiceException(ResultCode.USER_IS_EXISTS);
        }

        // 将用户注册dto实体转换为 User 实体对象
        User user = BeanUtil.bean2VO(userDTO, User.class);
        // 将当前时间设置为注册时间
        user.setRegisterTime(LocalDateTime.now());
        baseMapper.insert(user);
    }

    @Override
    public void updateUser(UserDTO userDTO) {
        User user = queryByUsername(userDTO.getUsername());
        // 如果根据用户名查询用户，该用户对象不为null，并且该用户的id与你的id不一致，那么说明该用户名已经被占用
        if (user != null && !Objects.equals(user.getId(), userDTO.getId())) {
            throw new ServiceException(ResultCode.USER_IS_EXISTS);
        }
        // 设置修改的条件
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
                .set(StringUtils.hasText(userDTO.getUsername()),
                        User::getUsername,userDTO.getUsername())
                .set(StringUtils.hasText(userDTO.getGender()),
                        User::getGender, userDTO.getGender())
                .set(StringUtils.hasText(userDTO.getPhone()),
                        User::getPhone, userDTO.getPhone())
                .set(StringUtils.hasText(userDTO.getAvatar()),
                        User::getAvatar, userDTO.getAvatar())
                .set(Objects.isNull(userDTO.getBirthday()),
                        User::getBirthday, userDTO.getBirthday())
                .eq(User::getId, userDTO.getId());
        // 修改符合条件的数据
        baseMapper.update(wrapper);
    }

    @Override
    public User queryById(Integer userId) {
        return baseMapper.selectById(userId);
    }


    private User queryByUsername(String username) {
        // 设置查询的wrapper条件
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
                .eq(User::getUsername, username);
        return baseMapper.selectOne(wrapper);
    }
}




